package com.ganbing518.commons.api.concurrent;

import com.ganbing518.commons.api.concurrent.support.ConcurrentRunnable;
import com.ganbing518.commons.api.concurrent.support.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Description:
 *
 * @author gan bing
 * @version V1.0
 * @date 2018-06-26 17:58
 */
public class ConcurrentExecutor {

    private final static Logger LOGGER = LoggerFactory.getLogger(ConcurrentExecutor.class);

    /**
     * 并发服务
     *
     * @param task     任务
     * @param maxNum   最大并发数
     * @param totalNum 总并发数
     */
    public static void execute(Task task, int maxNum, int totalNum) {

        if(task == null){
            throw new IllegalArgumentException("task is null");
        }
        if(totalNum < maxNum){
            throw new IllegalArgumentException("totalNum can't less than maxNum");
        }

        LOGGER.info("----------- ConcurrentService init");
        ExecutorService executor = Executors.newFixedThreadPool(maxNum);
        CountDownLatch begin = new CountDownLatch(1);
        CountDownLatch end = new CountDownLatch(totalNum);

        for (int i = 0; i < totalNum; i++) {
            executor.execute(new ConcurrentRunnable(begin, end, task, i));
        }
        LOGGER.info("----------- ConcurrentService start");
        begin.countDown();
        try {
            end.await();
        } catch (InterruptedException e) {
            LOGGER.error("ConcurrentService Interrupted Exception", e);
        }
        LOGGER.info("----------- ConcurrentService end");
        executor.shutdown();
    }
}
